Technical Q&A QA1124
Maintaining sessions in Java Applets on Mac OS X


Q: My Applet opens URLConnections to a JSP/servlet to transfer data back and forth, using the client's HttpSession on the server side to hold the data. But every subsequent connection the applet makes generates a new session with the server and my data is lost. This doesn't happen on Windows, or Mac OS 9. What's the problem?

A: Java applets on Mac OS X do not share cookies with the browser they are embedded in. This results in separate sessions for the applet and the browser, which can be problematic for some web applications. The solution is to rewrite the URL using a servlet/JSP/etc. when feeding the browser the content that embeds the applet, using the HttpServletResponse.encodeURL() method, for example. Listing 1 shows a simple JSP example.



<%
    HttpSession session1 = request.getSession(true);
%><HTML>    <BODY>    Browser's Session is <%= session1.getId() %><BR>
<%-- Write out APPLET tag --%> <APPLET CODEBASE="." CODE="TestApplet.class" WIDTH="500" HEIGHT="500"> <PARAM NAME="appName" VALUE="TestApplet"> <%-- Send the communication URL encoded with the session --%> <PARAM NAME="serverURL" VALUE="<%= response.encodeURL("serverIO.jsp") %>"> </APPLET> </BODY></HTML>

Listing 1. Sending a session-encoded URL to an applet.



The above code will encode the browser's session with the server into the applet's required URL for server communication. The applet, then, can get that URL as a parameter and use it to generate new, session-bound URLConnections. Listing 2 shows what this might look like.



    String ioData = "gkj3609&fj2*^bl#d?em";
    String param = "redirect";
// Get the serverURL Applet param with session info provided by the server StringBuffer serverURL = new StringBuffer(getParameter("serverURL"));
// Append URL parameters for server serverURL.append("?IOdata=").append(URLEncoder.encode(ioData)); serverURL.append("&param=").append(URLEncoder.encode(param));
// Construct final URL and get connection URL toGo = new URL(getDocumentBase(), serverURL.toString()); URLConnection conn = toGo.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); do { console.append(br.readLine()); console.append("\n"); } while (br.readLine() != null);

Listing 2. Constructing a URLConnection from a rewritten URL.



It is important that the session be encoded in the URL beginning with the entry point to the web application. This means that if your applet is contained in a JSP page called AppStart.jsp, then all links to AppStart.jsp should be URL-encoded using the call above. If the user navigates to the start page without the session encoded in the URL, and refreshes the page after the applet has begun communication, loss of the session information is possible.

To make this workaround successful, it will likely be necessary to disable cookie detection on your application server. The reason for this is that during every call to response.encodeURL(), most J2EE application servers only encode the URL if there is not an active cookie on the client representing the session. Therefore, if the browser creates a cookie for the session, the server will stop session-encoding its URLs because it will think that it is no longer necessary. The solution, then, is to disable cookies in the server so the URL is properly encoded at all times. Please note that this should not have any effect on a stateful web application that had been using cookies: URL rewriting is just as functional and persistent as client cookies.


[May 14 2002]


Developer Documentation | Technical Notes | Development Kits | Sample Code